import threading
import time


class PeriodicTimer:
     def __init__(self, interval):
         self._interval = interval
         self._flag = 0
         self._cv = threading.Condition()

     def start(self):
         t = threading.Thread(target=self.run)
         t.daemon = True
         t.start()

     def run(self):
         '''
         Run the timer and notify waiting threads after each interval
         '''
         while True:
             time.sleep(self._interval)
             with self._cv:  # <<<<
                 self._flag ^= 1
                 self._cv.notify_all()  # <<<<

     def wait_for_tick(self):
         '''
         Wait for the next tick of the timer
         '''
         with self._cv:  # <<<<
             last_flag = self._flag
             while last_flag == self._flag:
                self._cv.wait()  # <<<<


# Example use of the timer
ptimer = PeriodicTimer(0.2)
ptimer.start()


def countdown(n=10):
    while n > 0:
        ptimer.wait_for_tick()
        print(f'Count-DOWN {n}')
        n -= 1


def countup(n=8):
    i = 1
    while i <= n:
        ptimer.wait_for_tick()
        print(f'Count-UP {i}')
        i += 1


t1 = threading.Thread(target=countdown, args=(12,))
t1.start()

t2 = threading.Thread(target=countup, args=(8,))
t2.start()
